package Excle.GenerateExcelFile;

import emun.ToolErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.http.client.utils.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import utils.DateUtil;
import log_aop.OperationLog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author yangjicong
 * @date 2022/1/19
 *
 * 生成excel文件工具类
 */
@SuppressWarnings("ALL")
@Slf4j
@OperationLog
public class ExcelUtil {
    //日期正则表达式
    private static final Pattern PATTERN = Pattern.compile("^//d+(//.//d+)?$");
    //文件生成路径
    private static final String Path = "D:\\tool\\excel\\";

    public static String createExcel(ExportExcelModel excelModel) {
        Workbook wb = new XSSFWorkbook();
        //标题行抽出字段
        List<String> title = excelModel.getExcelTitleList();
        //设置sheet名称
        Sheet sheet = wb.createSheet(excelModel.getSheetName());
        //获取表头行
        Row titleRow = sheet.createRow(0);
        //创建单元格
        CellStyle style = wb.createCellStyle();
        //创建字体
        Font font = wb.createFont();

        /*设置格式*/
        setCellStyle(style,font);



        //标题
        Cell cell = null;
        for (int i = 0; i < title.size(); i++) {
            cell = titleRow.createCell(i);
            cell.setCellValue(title.get(i));
            cell.setCellStyle(style);
        }
        //写入excel文件
        Row row = null;
        int n = 0;
        if (excelModel.getExcelData() == null) {
            throw new BusinessException(ToolErrorCode.SYSTEM_INNER_ERROR.getCode(), ToolErrorCode.SYSTEM_INNER_ERROR.getDesc());
        }
        Iterator iterator = excelModel.getExcelData().iterator();
        while (iterator.hasNext()) {
            Object object = iterator.next();
            Field[] fields = object.getClass().getDeclaredFields();
            List<Object> objects = Arrays.stream(fields).filter(field -> !Modifier.isStatic(field.getModifiers()))
                    .filter(field -> PropertyUtils.isReadable(object, field.getName()))
                    .map(field -> {
                        try {
                            return PropertyUtils.getProperty(object, field.getName());
                        } catch (Exception e) {
                            log.error("createExcelData [{}]", e);
                            throw new BusinessException(ToolErrorCode.NOT_EXIST_ERROR.getCode(), ToolErrorCode.NOT_EXIST_ERROR.getDesc());
                        }
                    }).filter(Objects::nonNull).collect(Collectors.toList());
            row = sheet.createRow(n + 1);
            for (int i = 0; i < title.size(); i++) {
                Object o = objects.get(i);
                if (o instanceof Date) {
                    String textValue = null;
                    Date date = (Date) o;
                    textValue = DateUtils.formatDate(date, utils.DateUtil.DATE_PATTERN1);
                    if (null != textValue) {
                        Matcher matcher = PATTERN.matcher(textValue);
                        if (matcher.matches()) {
                            row.createCell(i).setCellValue(Double.parseDouble(textValue));
                        } else {
                            row.createCell(i).setCellValue(textValue);
                            // HSSFRichTextString richTextString = new HSSFRichTextString(textValue);
                        }
                        continue;
                    }
                }
                if (o instanceof Double) {
                    row.createCell(i).setCellValue((Double) o);
                    continue;
                }
                row.createCell(i).setCellValue(String.valueOf(o));
            }
            n++;
        }
        //设置单元格宽度自适应，在此基础上把宽度调至1.5倍
        for (int i = 0; i < title.size(); i++) {
            sheet.autoSizeColumn(i, true);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 15 / 10);
        }
        //获取配置文件中保存对应excel文件的路径
        String folderPath =Path;
        //创建上传文件目录
        File folder = new File(folderPath);
        //如果文件夹不存在创建对应的文件夹
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //设置文件名
        String fileName = excelModel.getSheetName() + DateUtil.getCurrent() + ".xlsx";
        String savePath = folderPath + fileName;
        OutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(savePath);
            wb.write(fileOut);
        } catch (IOException e) {
            log.error("异常" + e);
            if (fileOut != null) {
                try {
                    fileOut.close();
                } catch (IOException e1) {
                    log.error("异常" + e1);
                }
            }
        }
        //返回文件保存全路径
        return savePath;
    }

    private static void setCellStyle(CellStyle style, Font font) {
        // 设置字体
        font.setFontName("Arial");
        // 设置字体大小
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        // 居中
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        //设置单元格横向居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        // 填充
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        //设置前景色
        style.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());
        //设置背景色
        style.setFillForegroundColor(HSSFColor.DARK_YELLOW.index);

        //设置日期型数据的显示样式
        style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));


    }

}
